package com.qingzhuge.limiter.support;

import com.alibaba.csp.sentinel.cluster.client.config.ClusterClientAssignConfig;
import com.alibaba.csp.sentinel.cluster.client.config.ClusterClientConfig;
import com.alibaba.csp.sentinel.cluster.client.config.ClusterClientConfigManager;
import com.alibaba.csp.sentinel.datasource.ReadableDataSource;
import com.alibaba.csp.sentinel.datasource.nacos.NacosDataSource;
import com.alibaba.csp.sentinel.init.InitFunc;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.qingzhuge.limiter.configuration.SentinelProperties;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * @author zeroxiao
 * @date 2019/9/6 14:25
 */
public class NacosDataSourceInitFunc implements InitFunc {

    private SentinelProperties sentinelProperties;

    @Autowired
    public void setSentinelProperties(SentinelProperties sentinelProperties) {
        this.sentinelProperties = sentinelProperties;
    }

    @Override
    public void init() throws Exception {
        if (sentinelProperties != null) {
            //加载集群-信息
            loadClusterClientConfig();
            //动态数据源，注册集群限流规则
            registryClusterFlowRuleProperty();
        }
    }

    /**
     * 加载TokenServer 配置
     */
    private void loadClusterClientConfig() {
        //配置集群
        ClusterClientAssignConfig assignConfig = new ClusterClientAssignConfig();
        assignConfig.setServerHost(sentinelProperties.getTokenServerHost());
        assignConfig.setServerPort(sentinelProperties.getTokenServerPort());
        ClusterClientConfigManager.applyNewAssignConfig(assignConfig);

        //配置请求超时时间
        ClusterClientConfig clientConfig = new ClusterClientConfig();
        clientConfig.setRequestTimeout(sentinelProperties.getRequestTimeOut());
        ClusterClientConfigManager.applyNewConfig(clientConfig);
    }

    /**
     * 动态数据源，注册集群限流规则
     */
    private void registryClusterFlowRuleProperty() {
        ReadableDataSource<String, List<FlowRule>> rds =
                new NacosDataSource<>(
                        sentinelProperties.getNacosAddress(),
                        sentinelProperties.getGroupId(),
                        sentinelProperties.getNamespace() + sentinelProperties.getDataId(),
                        source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {}));

        FlowRuleManager.register2Property(rds.getProperty());
    }
}
